package com.foreverwin.jzymes.job;

import com.foreverwin.jzymes.common.domain.ResourceTimeSummary;
import com.foreverwin.jzymes.common.mapper.DashBoardAdviceMapper;
import com.foreverwin.jzymes.common.service.IProductionShiftService;
import com.foreverwin.jzymes.common.service.IResourceTimeSummaryService;
import com.foreverwin.jzymes.eap.domain.ResourceTimeLog;
import com.foreverwin.jzymes.eap.mapper.ResourceTimeLogAdviceMapper;
import com.foreverwin.jzymes.eap.service.IResourceTimeLogService;
import com.foreverwin.jzymes.framework.quartz.domain.SysJob;
import com.foreverwin.jzymes.framework.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.UUID;

@Service
public class ResourceTimeSummaryService {

    @Autowired
    IProductionShiftService productionShiftService;
    @Autowired
    IResourceTimeSummaryService resourceTimeSummaryService;
    @Autowired
    IResourceTimeLogService resourceTimeLogService;
    @Autowired
    ResourceTimeLogAdviceMapper resourceTimeLogAdviceMapper;
    @Autowired
    DashBoardAdviceMapper dashBoardAdviceMapper;

    Logger logger = LoggerFactory.getLogger( ResourceTimeSummaryService.class );

    private static final int TIME_UNIT = 60 * 1000;

    @Transactional( propagation = Propagation.REQUIRED, rollbackFor = Exception.class )
    public void computeResourceTime( SysJob job ){
        String site = job.getSite();

        List<ResourceTimeLog> resourceTimeLogList = dashBoardAdviceMapper.findPendingResourceTimeLogList( site );

        for( ResourceTimeLog resourceTimeLog : resourceTimeLogList ){
            Date startDateTime = resourceTimeLog.getStartDateTime();
            Date endDateTime = resourceTimeLog.getEndDateTime();
            Date lastSumTime = resourceTimeLog.getLastSumTime();



            logger.info( "设备：{}，状态：{}，开始时间：{}，结束时间：{}，上次汇总时间：{}", resourceTimeLog.getResrce(), resourceTimeLog.getStatus(), startDateTime != null ? DateUtil.format( startDateTime ) : "", endDateTime != null ? DateUtil.format( endDateTime ) : "", lastSumTime != null ? DateUtil.format( lastSumTime ) : "" );

            if( lastSumTime != null ){
                startDateTime = lastSumTime;
            }

            if( endDateTime != null ){
                sumResourceTime( resourceTimeLog, startDateTime, endDateTime, true );
            }else{
                sumResourceTime( resourceTimeLog, startDateTime, new Date(), false );
            }
        }

    }

    public void sumResourceTime( ResourceTimeLog resourceTimeLog, Date startDateTime, Date endDateTime, boolean isDone ){
        Date[] dateRange = productionShiftService.findShiftRange( resourceTimeLog.getSite(), startDateTime );
        if( endDateTime.before( dateRange[1] ) ){
            long elapsedTime = ( endDateTime.getTime() - startDateTime.getTime() ) / TIME_UNIT;
            logger.info( "开始时间：{}，结束时间：{}，汇总时间：{}", DateUtil.format( startDateTime ), DateUtil.format( endDateTime ), elapsedTime );
            saveResourceTimeSummary( resourceTimeLog.getSite(), resourceTimeLog.getResrce(), resourceTimeLog.getStatus(), elapsedTime, dateRange[0], dateRange[1] );
            if( isDone ){
                updateResourceTimeLog( resourceTimeLog, "true", null );
            }else{
                updateResourceTimeLog( resourceTimeLog, null, endDateTime );
            }
        }else{
            long elapsedTime = ( dateRange[1].getTime() - startDateTime.getTime() ) / TIME_UNIT;
            logger.info( "开始时间：{}，结束时间：{}，汇总时间：{}", DateUtil.format( startDateTime ), DateUtil.format( dateRange[1] ), elapsedTime );
            saveResourceTimeSummary( resourceTimeLog.getSite(), resourceTimeLog.getResrce(), resourceTimeLog.getStatus(), elapsedTime, dateRange[0], dateRange[1] );
            sumResourceTime( resourceTimeLog, dateRange[1], endDateTime, isDone );
        }
    }

    public void saveResourceTimeSummary( String site, String resource, String status, Long elapsedTime, Date startDateTime, Date endDateTime ){
        ResourceTimeSummary queryResourceTimeParam = new ResourceTimeSummary();
        queryResourceTimeParam.setSite( site );
        queryResourceTimeParam.setResrce( resource );
        queryResourceTimeParam.setStatus( status );
        queryResourceTimeParam.setStartDateTime( startDateTime );
        queryResourceTimeParam.setEndDateTime( endDateTime );
        List<ResourceTimeSummary> resourceTimeSummaryList = resourceTimeSummaryService.selectResourceTimeSummaryList( queryResourceTimeParam );

        if( resourceTimeSummaryList.size() > 0 ){
            ResourceTimeSummary resourceTimeSummary = resourceTimeSummaryList.get( 0 );
            resourceTimeSummary.setElapsedTime( resourceTimeSummary.getElapsedTime() + elapsedTime );
            resourceTimeSummaryService.updateResourceTimeSummary( resourceTimeSummary );
        }else{
            ResourceTimeSummary resourceTimeSummary = new ResourceTimeSummary();
            resourceTimeSummary.setHandle( UUID.randomUUID().toString() );
            resourceTimeSummary.setSite( site );
            resourceTimeSummary.setResrce( resource );
            resourceTimeSummary.setStatus( status );
            resourceTimeSummary.setElapsedTime( elapsedTime );
            resourceTimeSummary.setStartDateTime( startDateTime );
            resourceTimeSummary.setEndDateTime( endDateTime );
            resourceTimeSummaryService.insertResourceTimeSummary( resourceTimeSummary );
        }
    }

    public void updateResourceTimeLog( ResourceTimeLog resourceTimeLog, String isDone, Date lastSumTime ){
        resourceTimeLogAdviceMapper.selectResourceTimeLogForUpdate( resourceTimeLog.getHandle() );
        ResourceTimeLog updateResourceTimeLog = new ResourceTimeLog();
        updateResourceTimeLog.setHandle( resourceTimeLog.getHandle() );
        updateResourceTimeLog.setIsDone( isDone );
        updateResourceTimeLog.setLastSumTime( lastSumTime );
        resourceTimeLogAdviceMapper.updateResourceTimeLog( updateResourceTimeLog );
    }
}
